package com.yeskery.nut.application.sun;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.yeskery.nut.application.NutApplication;
import com.yeskery.nut.application.NutServer;
import com.yeskery.nut.core.*;
import com.yeskery.nut.http.sun.SunRequest;
import com.yeskery.nut.http.sun.SunResponse;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * SunServer Controller请求处理器
 * @author sprout
 * 2022-05-19 11:01
 */
public class ControllerHttpHandler implements HttpHandler {

    /** 日志对象 */
    private static final Logger logger = Logger.getLogger(ControllerHttpHandler.class.getName());

    /** Nut应用对象 */
    private final NutApplication nutApplication;

    /** 服务上下文 */
    private final ServerContext serverContext;

    /** 请求分发器 */
    private final Dispatcher dispatcher;

    /** Session管理器 */
    private final SessionManager sessionManager;

    /** 服务请求配置对象 */
    private final ServerRequestConfiguration serverRequestConfiguration;

    /** Nut 服务器 */
    private final NutServer nutServer;

    /**
     * 构建一个Controller请求处理器
     * @param nutApplication Nut应用对象
     * @param serverContext 服务上下文
     * @param dispatcher 请求分发器
     * @param sessionManager 会话管理器
     * @param serverRequestConfiguration 服务请求配置对象
     * @param nutServer Nut服务器对象
     */
    public ControllerHttpHandler(NutApplication nutApplication, ServerContext serverContext, Dispatcher dispatcher,
                                 SessionManager sessionManager, ServerRequestConfiguration serverRequestConfiguration, NutServer nutServer) {
        this.nutApplication = nutApplication;
        this.serverContext = serverContext;
        this.dispatcher = dispatcher;
        this.sessionManager = sessionManager;
        this.serverRequestConfiguration = serverRequestConfiguration;
        this.nutServer = nutServer;
    }

    @Override
    public void handle(HttpExchange httpExchange) throws IOException {
        try (InputStream inputStream = httpExchange.getRequestBody();
             OutputStream outputStream = httpExchange.getResponseBody()) {
            Request request = new SunRequest(httpExchange.getRemoteAddress(), httpExchange.getLocalAddress(),
                    serverContext, sessionManager, serverRequestConfiguration, httpExchange, inputStream);
            Response response = new SunResponse(nutApplication, outputStream, httpExchange);
            //请求执行的方法
            nutServer.process(request, response, dispatcher, sessionManager);
        } catch (Exception e) {
            logger.log(Level.WARNING, "An Error Occurred While Closing The SunServer Socket.", e);
            throw e;
        }
    }
}
